package com.atmilan.quartz.service.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.stream.Collectors;

import com.atmilan.quartz.model.entity.Discount;
import com.atmilan.quartz.service.IDiscountService;
import com.atmilan.quartz.utils.product.PrueProductUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.atmilan.quartz.constant.Constants;
import com.atmilan.quartz.constant.enums.ProductTypeEnum;
import com.atmilan.quartz.constant.enums.SyncStatusEnum;
import com.atmilan.quartz.model.dto.crmeb.StoreProductCrmebRequest;
import com.atmilan.quartz.model.dto.pure.PureProductResDTO;
import com.atmilan.quartz.model.dto.pure.PureProductResDTO.PureItem;
import com.atmilan.quartz.model.dto.pure.PureStockResDTO;
import com.atmilan.quartz.model.entity.crmeb.StoreProduct;
import com.atmilan.quartz.model.entity.crmeb.SystemConfig;
import com.atmilan.quartz.model.entity.pure.PureImages;
import com.atmilan.quartz.model.entity.pure.PureProduct;
import com.atmilan.quartz.model.entity.pure.PureProductSku;
import com.atmilan.quartz.service.IPureImagesService;
import com.atmilan.quartz.service.IPureProductService;
import com.atmilan.quartz.service.IPureProductSkuService;
import com.atmilan.quartz.service.IPureSyncService;
import com.atmilan.quartz.service.IStoreProductService;
import com.atmilan.quartz.service.ISystemConfigService;
import com.atmilan.quartz.utils.source.SourcePureProductUtil;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
public class PureSyncServiceImpl implements IPureSyncService {

    @Autowired
    ISystemConfigService systemConfigService;
    @Autowired
    IPureProductService pureProductService;
    @Autowired
    IPureProductSkuService pureProductSkuService;
    @Autowired
    IStoreProductService storeProductService;
    @Autowired
    SourcePureProductUtil sourcePureProductUtil;
    @Autowired
    IPureImagesService pureImagesService;
    @Autowired
    IDiscountService discountService;
    @Autowired
    PrueProductUtil prueProductUtil;

    @Override
    public Boolean syncPureProduct() {
        //数据清空
        pureProductService.deleteAll();
        pureProductSkuService.deleteAll();
        try {
            long millis = System.currentTimeMillis();
            List<PureProductResDTO> pureProductResDTOList = prueProductUtil.getPureProducts();
            if (CollectionUtils.isEmpty(pureProductResDTOList)) {
                log.info("--------------- pure获取商品接口请求失败 ---------------");
                return true;
            }
            List<PureStockResDTO> pureStockResDTOList = prueProductUtil.getPureStocks();
            if (CollectionUtils.isEmpty(pureStockResDTOList)) {
                log.info("--------------- pure获取商品库存接口请求失败 ---------------");
                return true;
            }
            //保存商品和sku
            saveGoods(pureProductResDTOList,pureStockResDTOList);
            log.info("--------------- pure远程抓取数据{}条, 总耗时: {} 分  ---------------", pureProductResDTOList.size(), (int) ((System.currentTimeMillis() - millis) / 1000 / 60));
        }catch (Exception e){
            e.printStackTrace();
        }
        return true;
    }

    /**
     * 商品源数据保存
     *
     */
    private void saveGoods(List<PureProductResDTO> pureProductResDTOList,List<PureStockResDTO> pureStockResDTOList) {
        List<PureProduct> goodList = new ArrayList<>();
        List<PureProductSku> skuList = new ArrayList<>();
        List<PureProductSku> skuCheckList = new ArrayList<>();
        List<PureStockResDTO> pureStockResDTONullList = new ArrayList<>();
        Map<String,PureProductSku> map = new HashMap<>();
        for (PureProductResDTO product : pureProductResDTOList) {
            PureProduct pureProduct = new PureProduct();
            BeanUtils.copyProperties(product,pureProduct,"id");
            pureProduct.setProductId(product.getId());
            goodList.add(pureProduct);
            if(CollectionUtils.isNotEmpty(product.getCombinations())){
                for (PureItem item : product.getCombinations()) {
                    PureProductSku sku = new PureProductSku();
                    BeanUtils.copyProperties(item,sku,"id");
                    sku.setProductId(product.getId());
                    sku.setSkuId(item.getId());
                    skuCheckList.add(sku);
                    map.put(sku.getEan13(),sku);
                }
            }
        }
        for (PureStockResDTO stock : pureStockResDTOList) {
            PureProductSku sku = map.get(stock.getEan());
            if(sku == null){
                pureStockResDTONullList.add(stock);
                continue;
            }
            sku.setQuantity(stock.getQuantity());
            skuList.add(sku);
        }
        pureProductService.saveBatch(goodList);
        pureProductSkuService.saveBatch(skuList);
    }

    @Override
    public Boolean pushPureProduct() {
        try {
            //当次更新少于500条, 则不更新, 并且重新拉取
            int count = pureProductService.count();
            if (500 > count) {
                systemConfigService.update(Wrappers.<SystemConfig>lambdaUpdate()
                        .eq(SystemConfig::getName, Constants.PURE_SYNC_STATUS)
                        .set(SystemConfig::getFormId, SyncStatusEnum.PUSH)
                        .set(SystemConfig::getUpdateTime, new Date())
                );
                log.info("--------------- PURE商品源数据, 少于规定条数, 不进行下发, 总条数为: {} ---------------", count);
                return false;
            }
            //将所有PURE商品更新状态置为未更新
            storeProductService.update(Wrappers.<StoreProduct>lambdaUpdate()
                    .eq(StoreProduct::getIsEurope, ProductTypeEnum.PURE.getCode())
                    .set(StoreProduct::getUpdateFlag, false)
            );

            //商品更新操作
            int pageNo = 1;
            int pageSize = 100;
            int maxPage = (count + pageSize - 1) / pageSize;
            log.info("--------------- 开始分页查询PURE商品源数据, 本次更新总条数为: {} ---------------", count);

            List<PureImages> imagesList = pureImagesService.list();
            Map<String, PureImages> imagesMap = imagesList.stream().collect(Collectors.toMap(PureImages::getEan13, e -> e));

            List<Discount> discountList = discountService.list(Wrappers.lambdaQuery(Discount.class).eq(Discount::getType,ProductTypeEnum.PURE.getCode()));

            long millis = System.currentTimeMillis();
            while (pageNo <= maxPage) {
                try {
                    PageHelper.startPage(pageNo, pageSize);
                    List<PureProduct> pureProductList = pureProductService.list();
                    PageInfo<PureProduct> pageInfo = PageInfo.of(pureProductList);
                    List<PureProduct> products = pageInfo.getList();
                    buildProduct(products,imagesMap,discountList);
                } catch (Exception e) {
                    e.printStackTrace();
                }

                log.info("--------------- PURE下发商品到数据库, 当前页数: {}, 总页数: {}, 耗时: {} 分 ---------------", pageNo, maxPage, (int) ((System.currentTimeMillis() - millis) / 1000 / 60));
                pageNo++;
            }
            // 图搜删除
            storeProductService.delSeachImage(ProductTypeEnum.PURE);
            // 下架所有未更新数据
            storeProductService.update(Wrappers.<StoreProduct>lambdaUpdate()
                    .eq(StoreProduct::getIsEurope, ProductTypeEnum.PURE.getCode())
                    .eq(StoreProduct::getUpdateFlag, false)
                    .eq(StoreProduct :: getIsShow, true)
                    .eq(StoreProduct :: getIsDel, false)
                    .set(StoreProduct::getIsShow, false)
                    .set(StoreProduct::getStock, 0)
                    .set(StoreProduct::getLastPushTime, new Date())
                    .set(StoreProduct::getIsTusou, false)
                    );
            // 下架所有sku库存
            storeProductService.downloadSku(ProductTypeEnum.PURE.getCode());
            
            return true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 商品构建处理
     *
     * @param products
     */
    private void buildProduct(List<PureProduct> products,Map<String, PureImages> imagesMap,List<Discount> discountList) {
        try {
            for (PureProduct product : products) {
                List<PureProductSku> skus = pureProductSkuService.list(Wrappers.lambdaQuery(PureProductSku.class)
                        .eq(PureProductSku::getProductId, product.getProductId())
                        .isNotNull(PureProductSku::getSize)
                        .gt(PureProductSku::getQuantity, 0)
                );
                List<PureProductSku> exceptionList = new ArrayList<>();
                for (PureProductSku productSku : skus) {
                    if(StringUtils.isBlank(productSku.getPriceExVat()) || new BigDecimal(productSku.getPriceExVat()).compareTo(BigDecimal.ZERO) < 1){
                        log.info("--------------- 该商品id:{}, sku: {} 售价异常, 不进行下放 ---------------",productSku.getProductId(),productSku.getSkuId());
                        exceptionList.add(productSku);
                    }
                }
                skus.removeAll(exceptionList);
                if (CollectionUtils.isEmpty(skus)) {
                    continue;
                }
                //颜色分组
                Map<String, List<PureProductSku>> colorMap = skus.stream().collect(Collectors.groupingBy(PureProductSku::getColor));

                for (Entry<String, List<PureProductSku>> entry : colorMap.entrySet()) {
                    List<PureProductSku> entryValue = entry.getValue();
                    //库存计算
                    int stock = entryValue.stream().mapToInt(e->Integer.parseInt(e.getQuantity())).sum();
                    if(stock == 0){
                        continue;
                    }
                    // 构建实体
                    StoreProductCrmebRequest storeProductCrmebRequest = sourcePureProductUtil.buildPureProduct(product, entryValue,imagesMap,discountList);
                    // 数据保存
                    StoreProduct storeProduct = storeProductService.getByBarCode(storeProductCrmebRequest.getBarCode(), storeProductCrmebRequest.getSuppliersId(), storeProductCrmebRequest.getKeyword());
                    boolean crmebUpdate = true;
                    if (null != storeProduct && null != storeProduct.getLastPushTime()) {
                        long txyye = (System.currentTimeMillis() - storeProduct.getLastPushTime().getTime()) / 1000 / 60;
                        if (60 > txyye) {
                            log.info("--------------- 该商品: {} 上次pure更新时间: {} 小于一小时, 不进行更新 ---------------", storeProductCrmebRequest.getBarCode(), storeProduct.getLastPushTime());
                            crmebUpdate = false;
                            storeProductService.update(Wrappers.<StoreProduct>lambdaUpdate()
                                    .eq(StoreProduct::getId, storeProduct.getId())
                                    .set(StoreProduct::getUpdateFlag, true)
                            );
                        }
                    }
                    if (crmebUpdate) {
                        storeProductService.saveOtProduct(storeProductCrmebRequest, storeProduct, stock);
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void getImageTask() {
        try {
            List<PureImages> pureImages = prueProductUtil.getPureImages();
            pureImagesService.saveBatch(pureImages);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}
